bitkeeper revision 1.1159.212.64 (42000361XrdUoEK_vD6RMga2eLmwZg)
authoriap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk>
Tue, 1 Feb 2005 22:32:01 +0000 (22:32 +0000)
committeriap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk>
Tue, 1 Feb 2005 22:32:01 +0000 (22:32 +0000)
Allow specification of backend vif MAC addresses. If a backend
MAC is not provided, generate one as before

Signed-off-by: Jody Belka <knew-xen@pimb.org>
Signed-off-by: ian.pratt@cl.cam.ac.uk
linux-2.6.10-xen-sparse/drivers/xen/netback/common.h
linux-2.6.10-xen-sparse/drivers/xen/netback/interface.c
tools/python/xen/lowlevel/xu/xu.c
tools/python/xen/xend/server/messages.py
tools/python/xen/xend/server/netif.py
tools/python/xen/xm/create.py
xen/include/public/io/domain_controller.h

index 0831cbe311a5b450234048ba5464f869ffa75941..c5146c486042ea05b486d47907fa74f7aaaadd3d 100644 (file)
@@ -35,6 +35,8 @@ typedef struct netif_st {
     domid_t          domid;
     unsigned int     handle;
 
+    u8               fe_dev_addr[6];
+
     /* Physical parameters of the comms window. */
     unsigned long    tx_shmem_frame;
     unsigned long    rx_shmem_frame;
index 9a3eea5932059cf3b74ff6c74ae9f3edf0fcbcf2..682ece07d9799e68d9cd1cb6615914cb5e593b70 100644 (file)
@@ -163,13 +163,24 @@ void netif_create(netif_be_create_t *create)
     /* Disable queuing. */
     dev->tx_queue_len = 0;
 
-    /*
-     * Initialise a dummy MAC address. We choose the numerically largest
-     * non-broadcast address to prevent the address getting stolen by an 
-     * Ethernet bridge for STP purposes. (FE:FF:FF:FF:FF:FF)
-     */
-    memset(dev->dev_addr, 0xFF, ETH_ALEN);
-    dev->dev_addr[0] &= ~0x01;
+    if ( (create->be_mac[0] == 0) && (create->be_mac[1] == 0) &&
+         (create->be_mac[2] == 0) && (create->be_mac[3] == 0) &&
+         (create->be_mac[4] == 0) && (create->be_mac[5] == 0) )
+    {
+        /*
+         * Initialise a dummy MAC address. We choose the numerically largest
+         * non-broadcast address to prevent the address getting stolen by an
+         * Ethernet bridge for STP purposes. (FE:FF:FF:FF:FF:FF)
+         */ 
+        memset(dev->dev_addr, 0xFF, ETH_ALEN);
+        dev->dev_addr[0] &= ~0x01;
+    }
+    else
+    {
+        memcpy(dev->dev_addr, create->be_mac, ETH_ALEN);
+    }
+
+    memcpy(netif->fe_dev_addr, create->mac, ETH_ALEN);
 
     rtnl_lock();
     err = register_netdevice(dev);
index 1e932deaf2c186eff01a714e9c920e45a66dc18b..12f27d63db26c1441ad0234c2481cd45c9296dd2 100644 (file)
@@ -917,6 +917,12 @@ static PyObject *xu_message_new(PyObject *self, PyObject *args)
         P2C(netif_be_create_t, mac[3],       u8);
         P2C(netif_be_create_t, mac[4],       u8);
         P2C(netif_be_create_t, mac[5],       u8);
+        P2C(netif_be_create_t, be_mac[0],    u8);
+        P2C(netif_be_create_t, be_mac[1],    u8);
+        P2C(netif_be_create_t, be_mac[2],    u8);
+        P2C(netif_be_create_t, be_mac[3],    u8);
+        P2C(netif_be_create_t, be_mac[4],    u8);
+        P2C(netif_be_create_t, be_mac[5],    u8);
         break;
     case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DESTROY):
         P2C(netif_be_destroy_t, domid,        u32);
index 34270e8ffbdafba2e0319b906c96d6e6765a1efe..4f9f9119a21f40176017bfbf8484070eda82365f 100644 (file)
@@ -330,9 +330,9 @@ def packMsg(ty, params):
     (major, minor) = msg_formats[ty]
     args = {}
     for (k, v) in params.items():
-        if k == 'mac':
+        if k in ['mac', 'be_mac']:
             for i in range(0, 6):
-                args['mac[%d]' % i] = v[i]
+                args['%s[%d]' % (k, i)] = v[i]
         else:
             args[k] = v
     msg = xu.message(major, minor, msgid, args)
index d63c3424352628285637b7abcba15c4d8db3261b..00ad1f138bd74b1297eb918e84813220a8f169be 100755 (executable)
@@ -109,7 +109,14 @@ class NetDev(controller.SplitDev):
         vmac = sxp.child_value(config, 'mac')
         if not vmac: return None
         mac = [ int(x, 16) for x in vmac.split(':') ]
-        if len(mac) != 6: raise XendError("invalid mac")
+        if len(mac) != 6: raise XendError("invalid mac: %s" % vmac)
+        return mac
+
+    def _get_config_be_mac(self, config):
+        vmac = sxp.child_value(config, 'be_mac')
+        if not vmac: return None
+        mac = [ int(x, 16) for x in vmac.split(':') ]
+        if len(mac) != 6: raise XendError("invalid backend mac: %s" % vmac)
         return mac
 
     def _get_config_ipaddr(self, config):
@@ -127,6 +134,7 @@ class NetDev(controller.SplitDev):
             return self.reconfigure(config)
         self.config = config
         self.mac = None
+        self.be_mac = None
         self.bridge = None
         self.script = None
         self.ipaddr = []
@@ -135,6 +143,7 @@ class NetDev(controller.SplitDev):
         if mac is None:
             raise XendError("invalid mac")
         self.mac = mac
+        self.be_mac = self._get_config_be_mac(config)
         self.bridge = sxp.child_value(config, 'bridge')
         self.script = sxp.child_value(config, 'script')
         self.ipaddr = self._get_config_ipaddr(config) or []
@@ -159,6 +168,7 @@ class NetDev(controller.SplitDev):
         """
         changes = {}
         mac = self._get_config_mac(config)
+        be_mac = self._get_config_be_mac(config)
         bridge = sxp.child_value(config, 'bridge')
         script = sxp.child_value(config, 'script')
         ipaddr = self._get_config_ipaddr(config)
@@ -166,6 +176,8 @@ class NetDev(controller.SplitDev):
         backendDomain = str(xd.domain_lookup(sxp.child_value(config, 'backend', '0')).id)
         if (mac is not None) and (mac != self.mac):
             raise XendError("cannot change mac")
+        if (be_mac is not None) and (be_mac != self.be_mac):
+            raise XendError("cannot change backend mac")
         if (backendDomain is not None) and (backendDomain != str(self.backendDomain)):
             raise XendError("cannot change backend")
         if (bridge is not None) and (bridge != self.bridge):
@@ -190,6 +202,8 @@ class NetDev(controller.SplitDev):
                ['idx', self.idx],
                ['vif', vif],
                ['mac', mac]]
+        if self.be_mac:
+            val.append(['be_mac', self.get_be_mac()])
         if self.bridge:
             val.append(['bridge', self.bridge])
         if self.script:
@@ -214,6 +228,11 @@ class NetDev(controller.SplitDev):
         """
         return ':'.join(map(lambda x: "%02x" % x, self.mac))
 
+    def get_be_mac(self):
+        """Get the backend MAC address as a string.
+        """
+        return ':'.join(map(lambda x: "%02x" % x, self.be_mac))
+
     def vifctl_params(self, vmname=None):
         """Get the parameters to pass to vifctl.
         """
@@ -267,6 +286,7 @@ class NetDev(controller.SplitDev):
         msg = packMsg('netif_be_create_t',
                       { 'domid'        : self.controller.dom,
                         'netif_handle' : self.vif,
+                        'be_mac'       : self.be_mac or [0, 0, 0, 0, 0, 0],
                         'mac'          : self.mac })
         self.getBackendInterface().writeRequest(msg, response=d)
         return d
index 12ce029c855dc17c9d0f5a2d9a63acdbebad0396..e79e02383cc19cb10980075d026ce0808599ecd3 100644 (file)
@@ -160,11 +160,13 @@ gopts.var('ipaddr', val="IPADDR",
           fn=append_value, default=[],
           use="Add an IP address to the domain.")
 
-gopts.var('vif', val="mac=MAC,bridge=BRIDGE,script=SCRIPT,backend=DOM",
+gopts.var('vif', val="mac=MAC,be_mac=MAC,bridge=BRIDGE,script=SCRIPT,backend=DOM",
           fn=append_value, default=[],
           use="""Add a network interface with the given MAC address and bridge.
           The vif is configured by calling the given configuration script.
           If mac is not specified a random MAC address is used.
+          The MAC address of the backend interface can be selected with be_mac.
+          If not specified then the network backend chooses it's own MAC address.
           If bridge is not specified the default bridge is used.
           If script is not specified the default script is used.
           If backend is not specified the default backend driver domain is used.
@@ -314,18 +316,22 @@ def configure_vifs(config_devs, vals):
             mac = d.get('mac')
             if not mac:
                 mac = randomMAC()
+            be_mac = d.get('be_mac')
             bridge = d.get('bridge')
             script = d.get('script')
             backend = d.get('backend')
             ip = d.get('ip')
         else:
             mac = randomMAC()
+            be_mac = None
             bridge = None
             script = None
             backend = None
             ip = None
         config_vif = ['vif']
         config_vif.append(['mac', mac])
+        if be_mac:
+            config_vif.append(['be_mac', be_mac])
         if bridge:
             config_vif.append(['bridge', bridge])
         if script:
@@ -423,7 +429,7 @@ def preprocess_vifs(opts, vals):
             (k, v) = b.strip().split('=', 1)
             k = k.strip()
             v = v.strip()
-            if k not in ['mac', 'bridge', 'script', 'backend', 'ip']:
+            if k not in ['mac', 'be_mac', 'bridge', 'script', 'backend', 'ip']:
                 opts.err('Invalid vif specifier: ' + vif)
             d[k] = v
         vifs.append(d)
index 682cd3921bc7c9494b36804aea292da8eb5d1708..c2abbc16bec7bccc59ad31a1c6d3312b99e8dfd4 100644 (file)
@@ -489,9 +489,11 @@ typedef struct {
     u32        netif_handle;  /*  4: Domain-specific interface handle.   */
     u8         mac[6];        /*  8 */
     u16        __pad1;        /* 14 */
+    u8         be_mac[6];     /* 16 */
+    u16        __pad2;        /* 22 */
     /* OUT */
-    u32        status;        /* 16 */
-} PACKED netif_be_create_t; /* 20 bytes */
+    u32        status;        /* 24 */
+} PACKED netif_be_create_t; /* 28 bytes */
 
 /*
  * CMSG_NETIF_BE_DESTROY: